<?php

namespace App\Admin\Forms;

use App\Models\Player;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Http\JsonResponse;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Exception;
use Illuminate\Support\Facades\Storage;
use PhpZip\Exception\ZipException;
use PhpZip\ZipFile;

class ImportPlayerForm extends Form implements LazyRenderable
{
    use LazyWidget;

    public function handle(array $input): JsonResponse
    {
        $zip = new ZipFile();

        try {
            $zip->openFromString(Storage::get($input['zip']), [
                'charset' => 'cp936',
            ]);

            $radio = 0;
            foreach ($zip->getListFiles() as $entryName) {
                if (!$zip->isDirectory($entryName)) {
                    $contents = $zip->getEntryContents($entryName);
                    $image = imagecreatefromstring($contents);
                    if (imagesx($image) > 750 || imagesx($image) < 375) {
                        imagedestroy($image);

                        return $this->response()->error('头像尺寸应介于375~750px之间');
                    }
                    $radio = imagesx($image) / imagesy($image);
                    imagedestroy($image);
                    break;
                }
            }

            foreach ($zip->getListFiles() as $entryName) {
                if (!$zip->isDirectory($entryName)) {
                    $contents = $zip->getEntryContents($entryName);
                    $image = imagecreatefromstring($contents);

                    if (imagesx($image) > 750 || imagesx($image) < 375) {
                        imagedestroy($image);

                        return $this->response()->error('头像尺寸应介于375~750px之间');
                    }
                    if (imagesx($image) / imagesy($image) != $radio) {
                        imagedestroy($image);

                        return $this->response()->error(
                            sprintf(
                                '[%s] 的头像尺寸与其他选手比例不一致',
                                pathinfo($entryName, PATHINFO_FILENAME)
                            )
                        );
                    }
                    imagedestroy($image);
                }
            }

            foreach ($zip->getListFiles() as $entryName) {
                if (!$zip->isDirectory($entryName)) {
                    $contents = $zip->getEntryContents($entryName);
                    $cover = date('Y/m/d/').md5($contents).'.'.pathinfo($entryName, PATHINFO_EXTENSION);
                    Storage::put($cover, $contents);
                    Player::create([
                        'chapter_id' => $this->payload['chapter_id'],
                        'name' => pathinfo($entryName, PATHINFO_FILENAME),
                        'cover' => $cover,
                        'status' => true,
                    ]);
                }
            }

            $zip->close();

            return $this->response()->success(sprintf('成功导入%s位选手', $zip->count()))->refresh();
        } catch (ZipException) {
            return $this->response()->error('压缩包打开失败');
        }
    }

    /**
     * @throws Exception
     */
    public function form(): void
    {
        $this->file('zip', '选手头像包')
            ->accept('zip')
            ->autoUpload()
            ->move(date('Y/m/d'))
            ->uniqueName()
            ->required()
            ->maxSize(102400)
            ->help('必须使用zip压缩文件');
    }
}
